<template>
  <div class="realtime-gauge" :style="getComponentStyle()">
    <div class="gauge-container">
      <!-- 使用SVG绘制仪表盘 -->
      <svg :width="gaugeSize" :height="gaugeSize" class="gauge-svg">
        <!-- 背景圆弧 -->
        <path
          :d="getArcPath(0, 100)"
          :stroke="props.backgroundColor"
          :stroke-width="props.strokeWidth"
          fill="none"
          class="gauge-bg"
        />

        <!-- 数值圆弧 -->
        <path
          :d="getArcPath(0, currentPercentage)"
          :stroke="getValueColor()"
          :stroke-width="props.strokeWidth"
          fill="none"
          class="gauge-value"
          :class="{ 'gauge-animated': props.animated }"
        />

        <!-- 中心文本 -->
        <text
          :x="gaugeSize / 2"
          :y="gaugeSize / 2 + 8"
          text-anchor="middle"
          class="gauge-text"
          :style="{ fontSize: props.textSize + 'px', fill: props.textColor }"
        >
          {{ formattedValue }}
        </text>

        <!-- 单位文本 -->
        <text
          v-if="props.showUnit && props.unit"
          :x="gaugeSize / 2"
          :y="gaugeSize / 2 + 28"
          text-anchor="middle"
          class="gauge-unit"
          :style="{ fontSize: props.textSize * 0.6 + 'px', fill: props.textColor }"
        >
          {{ props.unit }}
        </text>
      </svg>

      <!-- 状态指示器 -->
      <div v-if="props.showStatus" class="status-indicator">
        <div class="status-dot" :class="connectionStatus"></div>
        <span class="status-text">{{ getStatusText() }}</span>
      </div>
    </div>

    <!-- 标签 -->
    <div v-if="props.showLabel && props.label" class="gauge-label">
      {{ props.label }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
import { useAutoDataBinding } from '@/composables/use-data-binding';
import type { IDataBindingConfig } from '@/components/mt-edit/store/types';

// 组件属性定义
const props = defineProps({
  // 数据绑定配置
  dataBinding: {
    type: Object as () => IDataBindingConfig,
    default: () => ({
      enabled: false,
      sourceId: '',
      dataPointId: '',
      targetProperty: 'value',
      transform: 'number',
      defaultValue: '0',
      updateInterval: 0
    })
  },

  // 仪表盘属性
  value: {
    type: Number,
    default: 0
  },

  min: {
    type: Number,
    default: 0
  },

  max: {
    type: Number,
    default: 100
  },

  size: {
    type: Number,
    default: 120
  },

  strokeWidth: {
    type: Number,
    default: 8
  },

  backgroundColor: {
    type: String,
    default: '#e5e7eb'
  },

  primaryColor: {
    type: String,
    default: '#3b82f6'
  },

  warningColor: {
    type: String,
    default: '#f59e0b'
  },

  dangerColor: {
    type: String,
    default: '#ef4444'
  },

  successColor: {
    type: String,
    default: '#10b981'
  },

  textColor: {
    type: String,
    default: '#374151'
  },

  textSize: {
    type: Number,
    default: 16
  },

  // 阈值设置
  warningThreshold: {
    type: Number,
    default: 70
  },

  dangerThreshold: {
    type: Number,
    default: 90
  },

  // 显示选项
  showLabel: {
    type: Boolean,
    default: true
  },

  label: {
    type: String,
    default: '仪表盘'
  },

  showUnit: {
    type: Boolean,
    default: true
  },

  unit: {
    type: String,
    default: '%'
  },

  showStatus: {
    type: Boolean,
    default: true
  },

  animated: {
    type: Boolean,
    default: true
  },

  precision: {
    type: Number,
    default: 1
  }
});

// 响应式属性对象（用于数据绑定）
const componentProps = ref({
  value: props.value,
  min: props.min,
  max: props.max,
  label: props.label,
  unit: props.unit
});

// 使用数据绑定
const shouldUseDataBinding =
  props.dataBinding && props.dataBinding.enabled && props.dataBinding.targetProperty !== 'hide';
const dataBinding = useAutoDataBinding(
  shouldUseDataBinding ? props.dataBinding : null,
  componentProps.value,
  (property: string, value: any) => {
    // 直接更新响应式对象的属性
    if (componentProps.value.hasOwnProperty(property)) {
      (componentProps.value as any)[property] = value;
    }
  }
);

// 计算属性
const gaugeSize = computed(() => props.size);

const currentPercentage = computed(() => {
  const value = componentProps.value.value;
  const range = props.max - props.min;
  const normalizedValue = Math.max(0, Math.min(range, value - props.min));
  return (normalizedValue / range) * 100;
});

const formattedValue = computed(() => {
  const value = componentProps.value.value;
  if (value === null || value === undefined) {
    return '--';
  }
  return Number(value).toFixed(props.precision);
});

const connectionStatus = computed(() => {
  if (!props.dataBinding.enabled) return 'normal';
  return dataBinding.isConnected.value ? 'connected' : 'disconnected';
});

// 方法
const getArcPath = (startPercent: number, endPercent: number): string => {
  const radius = (gaugeSize.value - props.strokeWidth) / 2;
  const centerX = gaugeSize.value / 2;
  const centerY = gaugeSize.value / 2;

  // 仪表盘从 -90° 开始，顺时针 270° （3/4 圆）
  const startAngle = -90 + (startPercent / 100) * 270;
  const endAngle = -90 + (endPercent / 100) * 270;

  const startX = centerX + radius * Math.cos((startAngle * Math.PI) / 180);
  const startY = centerY + radius * Math.sin((startAngle * Math.PI) / 180);
  const endX = centerX + radius * Math.cos((endAngle * Math.PI) / 180);
  const endY = centerY + radius * Math.sin((endAngle * Math.PI) / 180);

  const largeArcFlag = endPercent - startPercent > 37.5 ? 1 : 0; // > 270°/8

  return `M ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${endX} ${endY}`;
};

const getValueColor = (): string => {
  const value = componentProps.value.value;
  if (value >= props.dangerThreshold) {
    return props.dangerColor;
  } else if (value >= props.warningThreshold) {
    return props.warningColor;
  } else {
    return props.primaryColor;
  }
};

const getStatusText = (): string => {
  if (!props.dataBinding.enabled) {
    return '静态模式';
  }
  return dataBinding.isConnected.value ? '实时数据' : '连接断开';
};

const getComponentStyle = (): Record<string, string> => {
  return {
    width: `${props.size + 20}px`,
    display: 'inline-flex',
    flexDirection: 'column',
    alignItems: 'center',
    gap: '8px'
  };
};

// 监听props变化，同步到响应式属性对象
watch(
  () => props.value,
  (newValue) => {
    if (!props.dataBinding?.enabled) {
      componentProps.value.value = newValue;
    }
  }
);

watch(
  () => props.min,
  (newValue) => {
    componentProps.value.min = newValue;
  }
);

watch(
  () => props.max,
  (newValue) => {
    componentProps.value.max = newValue;
  }
);

watch(
  () => props.label,
  (newValue) => {
    componentProps.value.label = newValue;
  }
);

watch(
  () => props.unit,
  (newValue) => {
    componentProps.value.unit = newValue;
  }
);
</script>

<style scoped>
.realtime-gauge {
  font-family:
    system-ui,
    -apple-system,
    sans-serif;
  user-select: none;
}

.gauge-container {
  position: relative;
  display: inline-block;
}

.gauge-svg {
  display: block;
}

.gauge-value {
  transition: stroke-dasharray 0.3s ease;
}

.gauge-value.gauge-animated {
  animation: gauge-fill 2s ease-out;
}

@keyframes gauge-fill {
  from {
    stroke-dasharray: 0 1000;
  }
  to {
    stroke-dasharray: 1000 0;
  }
}

.gauge-text {
  font-weight: 600;
  font-family: 'Arial', monospace;
}

.gauge-unit {
  font-weight: 400;
  opacity: 0.8;
}

.status-indicator {
  position: absolute;
  bottom: -20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #6b7280;
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

.status-dot.connected {
  background-color: #10b981;
}

.status-dot.disconnected {
  background-color: #ef4444;
}

.status-dot.normal {
  background-color: #6b7280;
}

.status-text {
  white-space: nowrap;
}

.gauge-label {
  font-size: 12px;
  font-weight: 500;
  color: #374151;
  text-align: center;
  margin-top: 4px;
}

/* 响应式设计 */
@media (max-width: 640px) {
  .gauge-label {
    font-size: 11px;
  }

  .status-indicator {
    font-size: 10px;
  }
}
</style>
